package redis;

import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import util.JedisPoolUtil;

import java.util.List;


/**
 * 秒杀类，完成秒杀
 * 防止库存遗留，需要使用LUA脚本来解决
 */
@SuppressWarnings({"all"})
public class SecKillRedis {

    private static final String redisHost = "192.168.45.128";

    private static final int redisPort = 6379;

    private static final String redisPassword = "lmy";

    @Test
    public void testRedis() {
        Jedis jedis = new Jedis(redisHost, redisPort);
        String pong = jedis.ping();
        System.out.println(pong);
    }

    /**
     * 秒杀方法
     * @param userId 用户id，后台生成
     * @param tickNo 票号，如北京-成都 bj_cd
     */
    public static boolean secKill(String userId, String tickNo) {
//        Jedis jedis = new Jedis(redisHost, redisPort);
//        jedis.auth(redisPassword);
        //通过连接池获取jedis连接
        JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();
        Jedis jedis = jedisPoolInstance.getResource();
        //拼接剩余票数对应的key
        String stockKey = "sk:" + tickNo + ":ticket";
        //拼接已抢票成功的用户的key
        String userKey = "sk:" + tickNo + ":user";
        //为防止超卖，监控库存
        jedis.watch(stockKey);
        if (check(jedis, userId, tickNo, stockKey, userKey)) {
            //购买
//            //1.扣减票库存
//            jedis.decr(stockKey);
//            //2.将该用户加入到抢购成功集合中
//            jedis.sadd(userKey, userId);
            //使用事务，完成秒杀
            Transaction multi = jedis.multi();
            //组队操作
            //1.扣减票库存
            multi.decr(stockKey);
            //2.将该用户加入到抢购成功集合中
            multi.sadd(userKey, userId);
            //3.执行
            List<Object> results = multi.exec();
            if (results == null || results.size() == 0) {
                System.out.println("抢票失败....");
                jedis.close();
                return false;
            }
            //如果这个jedis是从连接池获取的，这里jedis.close()就是将jedis连接释放回连接池
            jedis.close();
            System.out.println(userId + "秒杀成功....");
            return true;
        } else {
            return false;
        }
    }

    public static boolean check(Jedis jedis, String userId, String tickNo, String stockKey, String userKey) {
        if (userId == null || userId.length() == 0 || tickNo == null || tickNo.length() == 0) {
            return false;
        }
        //判断票数值是否为空
        if (stockKey == null || stockKey.length() == 0) {
            System.out.println("秒杀未开始，请等待......");
            jedis.close();
            return false;
        }
        //判断用户是否重复秒杀
        if (jedis.sismember(userKey, userId)) {
            System.out.println(userId + "不能复购......");
            jedis.close();
            return false;
        }
        //判断火车票是否有剩余
        int ticketNum = Integer.valueOf(jedis.get(stockKey));
        if (ticketNum <= 0) {
            System.out.println("票卖完了，秒杀结束......");
            jedis.close();
            return false;
        }
        return true;
    }




}
